#include <stdio.h>
#include "CMap.h"

/* --------------------------------------------------------------------------------
   CMap Class.
   The goal of this class is to reduce several screens of artworks 
   to a single screen of unique blocks. We want to reconstruct the
   original pictures from the Tile. To do that, we used an array 
   to hold the block data as it relates to the original pictures.
----------------------------------------------------------------------------------- */

//--------------------------------------------------------------------------------
// Name: CMap
// Desc: Constructor     
//--------------------------------------------------------------------------------
CMap::CMap(const char* FileTextName)
{
   LoadBaseFile(FileTextName);
}






//--------------------------------------------------------------------------------
// Name: LoadBaseFile
// Desc: Constructor     
//--------------------------------------------------------------------------------
void CMap::LoadBaseFile(const char* FileTextName)
{
   // The constructor read the file who contain informations
   // about Tile. Number of columns and of rows of blocks.
   // The structure of the file is easy.
   // line 1: total of tiles
   // line 2: total of columns
   // line 3: total of rows
   // line 4 to EOF: contain all number of block of fist row 
   //                of array at the end of the array. 
   //                Each data is separated by a comma.

   MAXTILES = MAXCOLS = MAXROWS = xTileStart = yTileStart = ScreenHeight = ScreenWidth = 0;
   XOffset = YOffset = 0;   
   TotHeightInPixel = TotWidthInPixel = 0;

/*
   MAXTILES = 6;
   MAXCOLS = 200;
   MAXROWS = 200;
   LevelMap = new int[MAXCOLS*MAXROWS];
   int i=0;
   while(i<MAXCOLS*MAXROWS){ LevelMap[i] = rand() % 6; i++;}   
*/

   if(FileTextName == NULL) InitFail("The name of the level file is null.");

   FILE *fp;

	if((fp = fopen(FileTextName, "r"))==NULL ) InitFail("Cannot open the level file.");
   else
   {
      char string[10];
      
      fgets(string,sizeof(string),fp);
      MAXTILES = atoi(string);

      fgets(string,sizeof(string),fp);
      MAXCOLS = atoi(string);

      fgets(string,sizeof(string),fp);
      MAXROWS = atoi(string);

      LevelMap = new int[MAXCOLS*MAXROWS];

      int c = 0,i=0;            
      while(i<MAXCOLS*MAXROWS)
      {      
         string[c] = fgetc(fp);
         while( string[c] != '\n' )            
         {                     
            if (string[c] == ',')
            {
               string[c] = NULL;
               LevelMap[i] =  atoi(string);
               i++;
               c=0;
            }      
            else
            {
               c++;
            }            
            string[c] = fgetc(fp);			
         }
      }      
      fclose(fp);
		
      // save(); method create a file with name res.txt and see if the data is loaded correctely.
   }

}


//--------------------------------------------------------------------------------
// Name: CMap
// Desc: Desstructor     
//--------------------------------------------------------------------------------
CMap::~CMap(void)
{
   // free memory
   delete [] LevelMap;
}







//--------------------------------------------------------------------------------
// Name: substr
// Desc: copy a string of a determinate string.
//--------------------------------------------------------------------------------
char* CMap::substr( char *s1, int startpos, int len )
{
   char* str = new char[len+1];
   
   if (s1 == NULL ) return NULL;
   for( int i=0; i<len ; i++ )
	 str[i] = s1[startpos+i];

   str[len]=NULL;
   return str;
}



//-----------------------------------------------------------------------------
// Name: GetResolution(int _ResolX, int _ResolY)
// Desc: This function get the handle of the current window.
//-----------------------------------------------------------------------------
void CMap::GetResolution(int _ResolX, int _ResolY)
{     
   ResolX = _ResolX; 
   ResolY = _ResolY;    
}



//-----------------------------------------------------------------------------
// Name: InitFail()
// Desc: This function is called if an initialization function fails
//-----------------------------------------------------------------------------
void CMap::
InitFail(LPCTSTR szError )
{
    MessageBox(NULL, szError, "Error detected on CMap Class", MB_OK);
}



//--------------------------------------------------------------------------------
// Name: GetBlock()
// Desc: This fonction give the current Tile.     
//--------------------------------------------------------------------------------
int CMap::
GetBlock(int Xpos, int Ypos)
{
   if( (Xpos > MAXCOLS || Ypos > MAXROWS) || (Xpos < 0 || Ypos < 0) ) return NULL;
   return LevelMap[Ypos*MAXCOLS+Xpos];
}


//--------------------------------------------------------------------------------
// Name: save()
// Desc: This fonction save on text fil with name res 
//       the datas of the array LevelMap.
//--------------------------------------------------------------------------------
void CMap::
save(void)
{  
   FILE *fp;

	if((fp = fopen("res.txt", "w"))==NULL ) InitFail("Cannot create the level file.");
   else
   {
      char str[10];
      int BASE = 10 ;

      itoa(MAXTILES,str,BASE);
      fputs(str,fp);  fputc('\n',fp);

      itoa(MAXCOLS,str,BASE);
      fputs(str,fp);  fputc('\n',fp);

      itoa(MAXROWS,str,BASE);
      fputs(str,fp);  fputc('\n',fp);

      for (int y=0; y < MAXROWS ;y++)
      {
         for (int x=0; x < MAXCOLS ;x++)
         {   
            itoa(LevelMap[y*MAXCOLS+x],str,BASE);
            fputs(str,fp);
            fputc(',',fp); 
         }
         fputc('\n',fp);          
      }
   }
   fclose(fp);
}





//--------------------------------------------------------------------------------
// Name: StartMap()
// Desc: This function draw the map.
// Note: Mandatory and must be used after GetResolution() method and 
//       after defined the width and height of blocks with
//       SetBlock() method.
//--------------------------------------------------------------------------------
void CMap::
StartMap( int XBlockArrayPos, int YBlockArrayPos)
{
   // the total lenght & width in pixel of the map.
   TotWidthInPixel = (MAXCOLS + 1) * Tile.TileWidth + Tile.TileWidth/2;
   TotHeightInPixel = (MAXROWS/2 + 1) * Tile.TileHeight; // -- If MAXROWS multiple of 2

   // current position in the integer array map block
   xTileStart = XBlockArrayPos; 
   yTileStart = YBlockArrayPos;
   
/*   // It's the position in the map
   XOffset = xTileDeb*Tile.TileWidth;
   YOffset = yTileDeb*Tile.TileHeight;
*/
   // count the maximum tile to draw on screen   
   ScreenMAPWidth = 8; // for the width
   ScreenMAPHeight = 16; // for the height


   XOffset = 64;
   YOffset = 0;
}



//--------------------------------------------------------------------------------
// Name: DrawMap()
// Desc: This fonction Draw the map.
//--------------------------------------------------------------------------------
void CMap::DrawMap(void)
{
   // scrolling horizontal
   if( XOffset >= Tile.TileWidth  )
   {
      XOffset = XOffset - Tile.TileWidth;
      xTileStart-- ;
   }
    
   else if( XOffset < 0 )
   {
	  XOffset = Tile.TileWidth + XOffset;
      xTileStart++ ;
   }

   // scrolling vertical
   if( YOffset >= (Tile.TileHeight /4))
   {
      YOffset = YOffset - (Tile.TileHeight /4);
      yTileStart-- ;
   }
   
   else if( YOffset < 0 )
   {
      YOffset = (Tile.TileHeight/4 ) + YOffset;
      yTileStart++ ;
   }


	// Drawing the Tiles
	// Ok, now we're ready to finally draw the tiles. I'll go through the code of this tile drawing function step by step.		
	
	// tile is our place holder variable that will be used in determining if the tile at map[y][x], for example, has an ID# of 0 or 1 when we loop through the map array.
   int xTileEnd = ScreenMAPWidth + xTileStart;
   int yTileEnd = ScreenMAPHeight + yTileStart;

   static SW = 1 ;

   FILE *fp;

   if (SW) fp = fopen("Infotile.txt", "w");
   int x=0,y=0,tile=0;
   for (int yPos = yTileStart-1; yPos < yTileEnd;  yPos++)      
   {      	  	  	   
      for (int xPos = xTileStart-1 ; xPos < xTileEnd; xPos++)
	  {
         x=0,y=0,tile=0;
	     //Here we have initialized a doubly-nested loop which will run through our map array, capture each tile's ID#, and then store that ID# in tile, as shown in the next step.
		 tile = GetBlock(xPos,yPos);
		 x = ( xPos - xTileStart - 1) * ( Tile.TileWidth ) + ( yPos & 1) * (Tile.TileWidth/2) + XOffset; 
	     y = ( yPos - yTileStart )    * ( Tile.TileWidth / 4 ) + YOffset;
		 Tile.DrawIsometricTile( x, ResolY-y, tile);

		 if (SW)
		 {
			char str[10];
			int BASE = 10 ;

			fputs("(xPos=",fp);
		    itoa(xPos,str,BASE);
			fputs(str,fp);  fputs(" , yPos=",fp);

			itoa(yPos,str,BASE);
			fputs(str,fp);  fputs(" , Tile=",fp);

			itoa(tile,str,BASE); fputs(str,fp);  
			
		    itoa(x,str,BASE); fputs(" , x=",fp);
			fputs(str,fp);  

		    itoa(y,str,BASE); fputs(" , y=",fp);
			fputs(str,fp);  

			fputs("), ",fp);             
			fputc('\n',fp);
		 }
      }
	  if(SW){ fputc('\n',fp); fputc('\n',fp); fputc('\n',fp); fputc('\n',fp); fputc('\n',fp);}
   }

   if (SW) { fclose(fp); SW = 1; }
}



//--------------------------------------------------------------------------------
// Name: ScrollRight()
// Desc: This method draw the scroll on right direction.
//--------------------------------------------------------------------------------
void CMap::
ScrollRight(int npixel)
{
   if( xTileStart <= MAXCOLS-(ScreenMAPWidth-2) )
   XOffset-=npixel;   
}



//--------------------------------------------------------------------------------
// Name: ScrollLeft()
// Desc: This method draw the scroll on left direction.
//--------------------------------------------------------------------------------
void CMap::
ScrollLeft(int npixel)
{
   if( xTileStart > 0 || (xTileStart == 0 && XOffset < Tile.TileWidth/2)) 
	   XOffset+=npixel;   
   
}



//--------------------------------------------------------------------------------
// Name: ScrollDown()
// Desc: This method draw the scroll on down direction.
//--------------------------------------------------------------------------------
void CMap::
ScrollDown(int npixel)
{
   if( yTileStart > 0 )
   YOffset+=npixel;
}



//--------------------------------------------------------------------------------
// Name: ScrollUp()
// Desc: This method draw the scroll on Up direction.
//--------------------------------------------------------------------------------
void CMap::
ScrollUp(int npixel)
{
   if( yTileStart < MAXROWS-(ScreenMAPHeight-1) )
   YOffset-=npixel;
}

